﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace 多配置源的优先级
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();

            ConfigurationBuilder configBuilder = new ConfigurationBuilder();

            //优先级：同一个属性，以最后一次读取为准。后面读取的数据会覆盖前面的数据。“后来居上”。
            
            //只要所有的配置中的数据能组成一个完成的配置对象（本例中的Config对象），那么访问Config对象的所有属性均不会报错。
            
            //如果，Config对象中某个属性，在所有的配置中均没有，而且该属性是一个class，那么试图访问该属性下面的属性时，程序运行就会报错。
            //也就是说，该属性对象为null，试图访问null对象的属性，就会报错。

            //从JSON文件读取
            configBuilder.AddJsonFile("config.json", true, true);

            //从命令行读取
            configBuilder.AddCommandLine(args);

            //从环境变量读取
            configBuilder.AddEnvironmentVariables();

            //从机密文件中读取（机密文件只会保存在本机，不会随项目一起上传到同步平台上，比如：github。）
            //所以，一般情况下，机密配置读取一般会放在所有读取的最前面。
            //机密配置只适用于开发环境。不适用于生成环境。生成环境一般直接就在配置文件、环境变量等配置了。
            configBuilder.AddUserSecrets<Program>();

            IConfigurationRoot configurationRoot = configBuilder.Build();

            services.AddOptions()
                .Configure<Config>(e => configurationRoot.Bind(e));
                //.Configure<Proxy>(e => configurationRoot.GetSection("proxy").Bind(e));

            services.AddScoped<GetConfigController>();
            using (var sp = services.BuildServiceProvider())
            {
                var controller = sp.GetRequiredService<GetConfigController>();
                controller.PrintConfig();
            }
        }
    }
}
